#include <iostream>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <QPainter>
#include <QFileDialog>
#include <QFontDialog>
#include <QColorDialog>
#include <QLineEdit>
#include <QTimer>
#include <pthread.h>
#include <QProcess>
#include <QMessageBox>
#include <QInputDialog>
#include <QDebug>
#include <fstream>
#include <QDateTime>
#include <stdlib.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/sendfile.h>
#include <netinet/in.h>
#include<sys/stat.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdint.h>
#include <termios.h>
//#include <Qimage>
#include "qt1.h"
#include "dlinklist.c"		//����dlinklist.h������ʾundefined reference

static int i=0;
int QQ=0,QW=1;
int W=0;
int cfd;
int fd_adc;
char buffer[1024];
int X=1,Y=1,Z=1;
//DLIST* Qt1:: p=NULL;
DLIST *p;
DLIST *q;
DLIST head;
int Speed=10;
void insert_dlinklist(DLIST *d,char *s);
//=====just for you to learn how to use comboBox=======
void Qt1::InitBox()
{
    comboBox1->clear();
    comboBox2->clear();

}

void Qt1::fun_refresh_label()
{
    t3.stop();
	//lb_sum->setText("photo");
	fun_refresh_pic();
}
//=====just for you to learn how to use comboBox=======

Qt1::Qt1(QWidget *parent):QDialog(parent)
{
  	setupUi(this);
//  rb_manual->setChecked(true);
    isCapOpen = false;
    isToSave = false;
    m_image = NULL;
	pb_prev->setDisabled(true);
	pb_next->setDisabled(true);
    pb_del->setDisabled(true);
    //Down->setDisabled(true);
    //Up->setDisabled(true);
    pb_prev->hide();
    pb_next->hide();
    pb_del->hide();
    pb_open->hide();
    OpenButton->hide();
    Up->hide();
    Down->hide();
    speed->hide();
    label3->hide();
    comboBox1->hide();
    comboBox2->hide();
//=====just for you to learn how to use comboBox=======
	InitBox();
	connect(&t3,SIGNAL(timeout()),this,SLOT(fun_refresh_label()));
	//t3.stop();
//=====just for you to learn how to use comboBox=======
	connect(pb_prev,SIGNAL(clicked()),this,SLOT(fun_prev()));
	connect(pb_next,SIGNAL(clicked()),this,SLOT(fun_pic()));
	connect(pb_del,SIGNAL(clicked()),this,SLOT(fun_delete()));
	connect(pb_open,SIGNAL(clicked()),this,SLOT(fun_open()));
	connect(OpenButton,SIGNAL(clicked()),this,SLOT(fun_cap_open()));
	connect(Log,SIGNAL(clicked()),this,SLOT(Login()));
	connect(Up,SIGNAL(clicked()),this,SLOT(Speedup()));
	connect(S1,SIGNAL(clicked()),this,SLOT(Xadd()));
	connect(S2,SIGNAL(clicked()),this,SLOT(Yadd()));
	connect(S3,SIGNAL(clicked()),this,SLOT(Zadd()));
	connect(Down,SIGNAL(clicked()),this,SLOT(Speeddown()));
  	connect(&t1,SIGNAL(timeout()),this,SLOT(fun_time()));
  	//connect(comboBox1, SIGNAL(clicked()), this, SLOT(SetP()));
  	t1.start(100);						//������ʱ�������1s��ÿ��1s�ᷢ��һ���ź�����ʵ�����߱�
  	//t3.start(Speed*10);
	init_dlinklist(&head);
    width = 640;
    height = 480;
    myCamera = new Camera("/dev/video0", width, height, 0);
    frameBufRGB = new unsigned char[width * height * 3];
    frameBufYUV = new unsigned char[width * height * 2];
}

void Qt1::SetP(){
    printf("QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ");
    if(QQ==1)fun_cap_open();
    QPixmap p(comboBox1->currentText());
	lb_pic->setPixmap(p);
	lb_pic->setScaledContents(1);
}

void Qt1::fun_refresh_pic()
{
   printf("fun_refresh_pic!!!\n");
   t3.stop();
   printf("fun_refresh_pic__!!!\n");
   if(!myCamera->GetBuffer(frameBufYUV))
   {
       std::cout<< "Get Camera Buf error!\n";
       return;
   }
   //TODO:process_image() function is now empty.
   printf("fun_refresh_picOVER!!!\n");
   myCamera->process_image(frameBufYUV, frameBufRGB);
   printf("fun_refresh_picOVER!!!!!\n");
   showCapPhoto();
   printf("fun_refresh_picOVER!!!!!!!\n");
   t3.start(Speed*10);

}
void Qt1::Speedup(){
    Speed+=1;
    speed->setText(QString::number(Speed));
    if(Speed==20)Up->setDisabled(true);
    Down->setDisabled(false);
    //t3.start(Speed*10);
}
void Qt1::Speeddown(){
    Speed-=1;
    speed->setText(QString::number(Speed));
    if(Speed==1)Down->setDisabled(true);
    Up->setDisabled(false);
    //t3.start(Speed*10);
}
void Qt1::Xadd()
{
    X=(X+1)%10;
    S1->setText(QString::number(X));
}
void Qt1::Yadd()
{
    Y=(Y+1)%10;
    S2->setText(QString::number(Y));
}
void Qt1::Zadd()
{
    Z=(Z+1)%10;
    S3->setText(QString::number(Z));
}
void Qt1::fun_cap_open()
{
    printf("OPEN!!!");
    //TODO: Use myCamera->OpenDevice() to open camera, and myCamera->CloseDevice() to close it.
    //You should think of it in two cases: camera closed and camera opened.
    //When you open camera, how to refresh image? Tips:use timer to trigge it.

    if(QQ==1)
    {
        QQ=0;
        //Down->setDisabled(false);
        //Up->setDisabled(false);
        OpenButton->setText("Open");
        //TakeButton->setDisabled(true);
        //myCamera->CloseDevice();
    }
    else
    {   QQ=1;
        //lb_R->setPixmap(QPixmap("/mnt/usb/a0.jpg"));
        pb_prev->setDisabled(true);
        pb_next->setDisabled(true);
        pb_del->setDisabled(true);
        //if(Speed!=10)Down->setDisabled(false);
        //if(Speed!=200)Up->setDisabled(false);
        OpenButton->setText("Close");
        //t3.start(Speed*10);
        //TakeButton->setDisabled(false);
        //t3.start(Speed*10);
        //fun_refresh_pic();
    }
    printf("CLOSE!!!");
}
void Qt1::fun_clean_pixmap()
{
    QPixmap p;
    lb_pic->setPixmap(p);
}



void Qt1::Login()
{
    if(X==2&&Y==3&&Z==3){
    Welcome->hide();
    Log->hide();
    S1->hide();
    S2->hide();
    S3->hide();
    myCamera->OpenDevice();
    pb_prev->show();
    pb_next->show();
    pb_del->show();
    pb_open->show();
    OpenButton->show();
    Up->show();
    Down->show();
    speed->show();
    label3->show();
    comboBox1->show();
    comboBox2->show();
    int recbyte;
	int sin_size;
	struct sockaddr_in s_add, c_add;
	unsigned short portnum = 2333;
	char *adc = "/dev/adc";
    fd_adc = ::open(adc, O_RDWR|O_NOCTTY|O_NDELAY);
	printf("Hello,welcome to client!\r\n");



	cfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == cfd)
	{
			printf("socket fail ! \r\n");
			return ;
	}

	printf("socket ok !\r\n");

	bzero(&s_add,sizeof(struct sockaddr_in));
	s_add.sin_family=AF_INET;
	s_add.sin_addr.s_addr= inet_addr("192.168.1.112");
	s_add.sin_port=htons(portnum);
	printf("s_addr = %#x ,port : %#x\r\n",s_add.sin_addr.s_addr,s_add.sin_port);

	if(-1 == ::connect(cfd,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))
	{
			printf("connect fail !\r\n");
			//return ;
	}

	printf("connect ok !\r\n");
    t3.start(Speed*10);}

    //TODO: When this button is clicked, we take a photo and save it.
    /*QQ=0;
    char filename[20];
    //QDateTime d=QDateTime::currentDateTime();	//��ȡ��ǰʱ��,currentDateTime()��һ����̬����
    //lb_time->setText(d.toString("yyyy-MM-dd-ddd hh:mm:ss"));
    if(m_image != NULL){
    sprintf(filename, "/mnt/usb/a%d.jpg", W++);
    printf("%s\n",filename);
    m_image->save(filename,"JPG",-1);
    }
    QQ=1;*/
}
void Qt1::showCapPhoto()
{
    printf("showCapPhoto!!!\n");
    if(m_image != NULL)
        delete m_image;
    m_image = NULL;
    m_image = new QImage(frameBufRGB, width, height, QImage::Format_RGB888);
    if(QQ==1){lb_pic->setPixmap(QPixmap::fromImage(*m_image));}
    else{QPixmap p(comboBox1->currentText());
	lb_pic->setPixmap(p);
	lb_pic->setScaledContents(1);}
    //QDateTime d=QDateTime::currentDateTime();	//��ȡ��ǰʱ��,currentDateTime()��һ����̬����
    send(cfd,"file",strlen("file"),0);
    char filename[100];
    sprintf(filename, "/mnt/usb/aa%d.jpg", W++);
    //sprintf(filename, "/mnt/usb/%s.jpg",(d.toString("yyyy-MM-dd-ddd hh:mm:ss").toStdString()));
    printf("%s\n",filename);
    m_image->save(filename,"JPG",-1);
    send(cfd,filename,strlen(filename),0);
    int recbyte = read(cfd, buffer, 1024);
    while(recbyte!=-1&&buffer[0]!='O')
        recbyte = read(cfd, buffer, 1024);
    int fd;
    fd = ::open(filename,O_RDWR,0777);
    struct stat stat_buf;
    ::fstat(fd,&stat_buf);
    ::sendfile(cfd,fd,NULL,stat_buf.st_size);
    ::close(fd);
    int en=read(fd_adc,buffer,10);
    int ans=atoi(buffer);
    ans=ans*10000/4095;
    char text[100];
    sprintf(text, "Resistance:%d", ans);
    lb_R->setText(text);
    if(ans<1000)lb_State->setText("State:Too Low");
    if(ans>9000)lb_State->setText("State:Too High");
    if(ans>=1000&&ans<=9000)lb_State->setText("State:Normal");
    sprintf(text, "%d", ans);
    QStringList strList;
    strList<<text;
    comboBox2->addItems(strList);
    while(recbyte!=-1&&buffer[0]!='O')
        recbyte = read(cfd, buffer, 1024);
    send(cfd,text,strlen(text),0);
    memset(buffer,0,sizeof(buffer));
    recbyte = read(cfd, buffer, 1024);
    buffer[recbyte]='\0';
    int Len=atoi(buffer);
    if(Len==1){
        remove(filename);}
        else{QStringList strList;
    strList<<filename;
    comboBox1->addItems(strList);}
}


void Qt1::fun_time()
{
    QDateTime d=QDateTime::currentDateTime();	//��ȡ��ǰʱ��,currentDateTime()��һ����̬����
    lb_time->setText(d.toString("yyyy-MM-dd-ddd hh:mm:ss"));	//����ʱ���ʽ
}

void Qt1::fun_pic()
{
	i++;
	if(i==(len+1))i=1;

	p=p->next;
	display_pic();
}


void Qt1::fun_prev()	//fun_next()��fun_pic()һ��
{
	i--;
	if(i==0)i=len;

	p=p->prev;
	display_pic();
}

void Qt1::display_pic()
{
	QString buf(p->path);
	QPixmap p(buf);
	lb_pic->setPixmap(p);
	lb_pic->setScaledContents(1);
	//label->setText(buf);
	lb_num->setText(QString::number(i));
	lb_sum->setText(QString::number(len));
}


void Qt1::fun_delete()
{
	int ret;
        ret=QMessageBox::warning(this, tr("m_image browser"),
					   tr("Are you sure to delete it?"),
					   QMessageBox::Yes | QMessageBox::No,
					   QMessageBox::No);
	if(ret==QMessageBox::Yes)
	{
		remove(p->path);
		DLIST *r=(&head)->next;
		int n=1;
		while(r!=p)		//�ҵ���ǰ p��λ��
		{
			n++;
			r=r->next;
		}
		p=p->next;
		del_dlinklist(&head,n);
		if(i==len)i--;
		len=legnth_dlinklist(&head);
		display_pic();
	}
//	dlinkilist_tofile(&head);
}

void Qt1::fun_open()
{
	QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                 "/mnt/disk/qrssy/photo2",
                                                 tr("Images (*.png *.xpm *.jpg)"));
	printf("open folder!\n");
	if(fileName!=NULL)
	{
		init_dlinklist(&head);	//Ϊ����һ��Ŀ¼��׼��
		char *str;
		char filename[100]={0};
		DIR *dp;					//ָ��Ŀ¼
		struct dirent *dirp;		//ָ��Ŀ¼��(��������Ŀ¼����ͨ�ļ�)

		int m=strlen(fileName.toAscii().data());
		str=(char*)malloc(m);
		strcpy(str,fileName.toAscii().data());
		strcpy(filename,str);

		QString buf(fileName.toAscii().data());
		QPixmap first(buf);
		lb_pic->setPixmap(first);
		lb_pic->setScaledContents(1);
        //label->setText(buf);
		strip(filename);
		dp=opendir(filename);
		while(dirp=readdir(dp))
		{
			if(judge(dirp->d_name)==1)
			{
				strcat(filename,"/");
				strcat(filename,dirp->d_name);	//�ļ����ڵ�Ŀ¼+�ļ���=����·��
				printf("%s\n",filename);
				insert_dlinklist(&head,filename);
				filename[strlen(filename)-strlen(dirp->d_name)-1]='\0';
			}
		}
		q->next=(&head)->next;
		(&head)->next->prev=q;

		len=legnth_dlinklist(&head);
		int pos=1;
		DLIST *r=(&head)->next;
		while(strcmp(r->path,str)!=0)
		{
			r=r->next;
			pos++;
		}
		p=r;
		i=pos;
		lb_num->setText(QString::number(i));
		lb_sum->setText(QString::number(len));

		pb_prev->setDisabled(false);
		pb_next->setDisabled(false);
		pb_del->setDisabled(false);
//		display_pic();
	}
	if(QQ==1)
        fun_cap_open();
//	dlinkilist_tofile(&head);
}

void Qt1::strip(char *s)
{
	char *p=s;
	int n=0;
	while(*p)
	{
		if(*p=='/')
		{
			n++;
		}
		p++;
	}
	if(n==1)
	{
		s[1]='\0';
	}
	else
	{
		p--;
		while(*p)
		{
			if(*p=='/')
			{
				*p='\0';
				break;
			}
			p--;
		}
	}
}

int Qt1::judge(char * s)
{
	int i,len=strlen(s);
	char *p=s;
	if(len<5)
	{
		return 0;
	}
	else
	{
		while(*p)
		{
			p++;
		}
		for(i=0;i<4;i++)p--;
		if((strncmp(p,".jpg",4)==0)||(strncmp(p,".png",4)==0)||(strncmp(p,".xpm",4)==0))
		{
			return 1;
		}
		else
			return 0;
	}
}

void insert_dlinklist(DLIST *d,char *s)	//������ĩβ����,֮���԰���������ᵽ�������Ϊ����ʹ��ȫ�ֱ���DLIST *q
{
	DLIST *r=d;
//	DLIST *q;
	q=(DLIST*)malloc(sizeof(DLIST));	//�����q�����Ǿֲ��ģ������޷��γ�˫��ѭ������
	memset(q,0,sizeof(q));
	strcpy(q->path,s);

	if(r->next==NULL)
	{
		r->next=q;
		q->next=NULL;
	}
	else
	{
		while(r->next!=NULL)
		{
			r=r->next;
		}
		r->next=q;
		q->prev=r;
		q->next=NULL;
	}
	printf("insert success\n");
}


Qt1::~Qt1()
{
    delete[] frameBufRGB;
    delete[] frameBufYUV;
    delete m_image;
}
